﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using SpaceGame.Enemies;
using SpaceGame.Managers;
using SpaceGame.Particles;

namespace SpaceGame.Player
{
    public class PlayerShip : DrawableGameComponent
    {
        #region Private Fields

        private KeyboardState m_LastKeyboardState;
        private GamePadState m_LastGamePadState;
        private Texture2D m_SpaceTexture;
        private SpriteBatch m_SpriteBatch;
        private List<Missile> m_Missiles;
        private List<BaseEnemy> m_Enemies;

        private Vector2 m_Location;
        private Vector2 m_ShipSize;
        private float m_Rotation;
        private int m_Speed;
        private int m_MaxSpeed;
        private int m_Rights = 3;
        private float m_Scale;
        private int m_Score;

        private DateTime m_LastMissileTime;

        #endregion

        #region Attributes

        public int Score
        {
            get { return m_Score; }
            set { m_Score = value; }
        }

        public int Rights
        {
            get { return m_Rights; }
            set 
            { 
                m_Rights = value;
                if (m_Rights <= 0)
                    GameStateManager.GameState = GameState.GameOver;
            }
        }

        public List<BaseEnemy> Enemies
        {
            get { return m_Enemies; }
            set { m_Enemies = value; }
        }

        public Vector2 ShipSize
        {
            get { return m_ShipSize; }
            set { m_ShipSize = value; }
        }

        public float Scale
        {
            get { return m_Scale; }
            set { m_Scale = value; }
        }

        public int MaxSpeed
        {
            get { return m_MaxSpeed; }
            set { m_MaxSpeed = value; }
        }

        public int Speed
        {
            get { return m_Speed; }
            set { m_Speed = value; }
        }

        public float Rotation
        {
            get { return m_Rotation; }
            set { m_Rotation = value; }
        }

        public Vector2 Location
        {
            get { return m_Location; }
            set { m_Location = value; }
        }

        #endregion

        public PlayerShip(Game game) : base(game)
        {
            m_SpriteBatch = new SpriteBatch(game.GraphicsDevice);
            m_Missiles = new List<Missile>();
            m_LastMissileTime = new DateTime();
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            m_SpaceTexture = Game.Content.Load<Texture2D>("Textures/Player/ship");
            m_ShipSize = new Vector2(m_SpaceTexture.Width, m_SpaceTexture.Height);
            base.LoadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            if (GameStateManager.GameState != GameState.Playing)
                return;

            if (m_SpriteBatch == null)
                m_SpriteBatch = new SpriteBatch(Game.GraphicsDevice);

            m_SpriteBatch.Begin();

            for(int i = 0; i < m_Missiles.Count; i++)
                if (m_Missiles[i].IsAlive)
                    m_SpriteBatch.Draw(m_Missiles[i].MissileTexture, m_Missiles[i].Location, null, Color.White, m_Missiles[i].Rotation,
                        m_Missiles[i].Center, 1f, SpriteEffects.FlipHorizontally, 1.0f);

            m_SpriteBatch.Draw(m_SpaceTexture, m_Location, null
                , Color.White, m_Rotation,
                new Vector2(m_SpaceTexture.Width / 2, m_SpaceTexture.Height / 2), m_Scale, SpriteEffects.None,
                1.0f);

            m_SpriteBatch.End();

            base.Draw(gameTime);
        }

        public override void Update(GameTime gameTime)
        {
            if (GameStateManager.GameState != GameState.Playing)
                return;

            KeyboardState keyboardState = Keyboard.GetState();
            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);

            if (keyboardState.IsKeyDown(Keys.W))
                m_Location.Y -= m_Speed;
            if(keyboardState.IsKeyDown(Keys.S))
                m_Location.Y += m_Speed;
            if (keyboardState.IsKeyDown(Keys.A))
                m_Location.X -= m_Speed;
            if (keyboardState.IsKeyDown(Keys.D))
                m_Location.X += m_Speed;

            //if (keyboardState.IsKeyUp(Keys.Space) && m_LastKeyboardState.IsKeyDown(Keys.Space))
            //    ParticleManager.Explosion(m_Location, 600);

            if (keyboardState.IsKeyDown(Keys.Space))
            {
                if ((DateTime.Now - m_LastMissileTime).TotalSeconds > 0.09)
                {
                    Missile missile = new Missile(
                        Game.Content.Load<Texture2D>("Textures/Missiles/missile-default"),
                        MissileType.Patriot,
                        m_Rotation,
                        m_Location);
                    m_Missiles.Add(missile);
                    m_LastMissileTime = DateTime.Now;
                }
            }

            if (m_Missiles.Count > 0)
            {
                for (int i = 0; i < m_Missiles.Count; i++)
                {
                    for (int k = 0; k < m_Enemies.Count; k++)
                    {
                        Rectangle enemyRectangle = new Rectangle((int)m_Enemies[k].Location.X, (int)m_Enemies[k].Location.Y,
                            (int)m_Enemies[k].Texture.Width, (int)m_Enemies[k].Texture.Height);

                        Rectangle missileRectangle = new Rectangle((int)m_Missiles[i].Location.X, (int)m_Missiles[i].Location.Y,
                            (int)m_Missiles[i].MissileTexture.Width, (int)m_Missiles[i].MissileTexture.Height);

                        if (missileRectangle.Intersects(enemyRectangle))
                        {
                            m_Missiles[i].IsAlive = false;
                            m_Score += m_Enemies[k].Point;
                            m_Enemies[k].Destroy();
                        }
                    }

                    if (m_Missiles[i].Location.X > Game.GraphicsDevice.PresentationParameters.BackBufferWidth ||
                        m_Missiles[i].Location.Y > Game.GraphicsDevice.PresentationParameters.BackBufferHeight)
                        m_Missiles[i].IsAlive = false;

                    if (m_Missiles[i].IsAlive)
                    {
                        m_Missiles[i].Location += m_Missiles[i].Velocity;
                    }
                    else
                        m_Missiles.Remove(m_Missiles[i]);
                }
            }

            if (m_Location.X - 40 < 0)
                m_Location.X = 40;
            if (m_Location.X + 40 > Game.GraphicsDevice.PresentationParameters.BackBufferWidth)
                m_Location.X = Game.GraphicsDevice.PresentationParameters.BackBufferWidth - 40;
            if (m_Location.Y - 40 < 0)
                m_Location.Y = 40;
            if (m_Location.Y + 40 > Game.GraphicsDevice.PresentationParameters.BackBufferHeight)
                m_Location.Y = Game.GraphicsDevice.PresentationParameters.BackBufferHeight - 40;

            #region Size

            if (keyboardState.IsKeyDown(Keys.Home))
                m_Scale += 0.02f;
            
            if (keyboardState.IsKeyDown(Keys.End))
                m_Scale -= 0.02f;

            #endregion

            if (keyboardState.IsKeyDown(Keys.Left))
                m_Rotation -= 0.08f;

            if (keyboardState.IsKeyDown(Keys.Right))
                m_Rotation += 0.08f;

            m_LastKeyboardState = Keyboard.GetState();
            m_LastGamePadState = GamePad.GetState(PlayerIndex.One);

            base.Update(gameTime);
        }

        public void Destroy(BaseEnemy enemy)
        {
            ExplosionParticleSystem explosion = new ExplosionParticleSystem(Game, 1);
            Game.Components.Add(explosion);
            explosion.AddParticles(m_Location);
            m_Enemies.Remove(enemy);
            Rights--;
        }

        public void Destroy()
        {
            ExplosionParticleSystem explosion = new ExplosionParticleSystem(Game, 1);
            Game.Components.Add(explosion);
            explosion.AddParticles(m_Location);
            Rights--;
        }
    }
}